﻿using System;
using System.Net;
using System.Windows;
using System.Threading;

namespace UnitDriven.Commanding
{
	public abstract class CommandBase : ICommand
	{
		/// <summary>
		/// Default timeout is 30 seconds.
		/// </summary>
		public static readonly TimeSpan DefaultTimeout = TimeSpan.FromSeconds(30);

		private object _userState;
		private TimeSpan _timeout;

		public virtual object UserState
		{
			get { return _userState; }
		}

		public virtual TimeSpan Timeout
		{
			get { return _timeout; }
		}

		protected CommandBase()
			: this(CommandBase.DefaultTimeout, null)
		{ }

		protected CommandBase(TimeSpan timeout, object userState)
		{
			_timeout = timeout;
			_userState = userState;
		}

		public event EventHandler<CommandCompleteEventArgs> Complete;

		protected virtual void OnComplete(Exception exception)
		{
			OnComplete(new CommandCompleteEventArgs(exception));
		}

		protected virtual void OnComplete(CommandCompleteEventArgs e)
		{
			if (Complete != null)
				Complete(this, e);
		}

		protected virtual void Initialize()
		{
		}

		public abstract void Execute();

		void ICommand.Initialize()
		{
			Initialize();
		}

		void ICommand.Execute()
		{
			Execute();
		}

		protected virtual void Dispose(bool disposing)
		{
		}

		public void Dispose()
		{
			Dispose(true);
			GC.SuppressFinalize(this);
		}
	}
}
